package com.tang.multi.v3;

import lombok.extern.slf4j.Slf4j;

import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * @author Tang
 * @classname Acceptor
 * @description [ 请求接收 ]
 * @date 2021/8/10 14:00
 */
@Slf4j
public class Acceptor implements Runnable {

    private final int core = 3;

    private int index = 0;

    private SubReactor[] subReactors = new SubReactor[core];

    private ServerSocketChannel serverSocketChannel;

    public Acceptor(ServerSocketChannel serverSocketChannel) {
        this.serverSocketChannel = serverSocketChannel;
        for (int i = 0; i < this.core; i++) {
            subReactors[i] = new SubReactor(i);
            Thread thread = new Thread(subReactors[i]);
            thread.setDaemon(true);
            thread.start();
            // 监听事件
            log.info("{}号SubRector等待处理事件...", i);
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                log.info("Acceptor等待连接处理...");
                SocketChannel socketChannel = this.serverSocketChannel.accept();
                socketChannel.configureBlocking(false);
                // 轮询负载一个 subReactor
                SubReactor subReactor = this.subReactors[this.index++ % this.core];
                // 当前channel注册到选择器
                SelectionKey selectionKey = socketChannel.register(subReactor.getSelector(), SelectionKey.OP_READ);
                log.info("当前连接{},注册到{}号SubRector上...", socketChannel.hashCode(), subReactor.getId());
                subReactor.setSelectionKey(selectionKey);
                subReactor.getSelector().wakeup();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}